# usarcore.py
# Creates a non-blocking socket connection and uses it to route incoming robot
# connections.

import errno;
import socket;
import GameLogic;

import usarrobot;
import usarmsg;

USAR_PORT = 3000

class Core:
    def __init__(self):
        self._serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM);
        self._serverSocket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
        self._serverSocket.setblocking(0);
        self._serverSocket.bind(('', USAR_PORT));
        self._serverSocket.listen(1);
        self._unknownClients = {};
        
    def attachClient(self, init, client):
        try:
            name = init[0].group("name");
            if name in GameLogic.robots:
                robot = GameLogic.robots[name];
                robot.setClient(client, self._unknownClients[client], init);
            else:
                client.close();
                print "Robot not found: " + name;
                print GameLogic.robots;
        except AttributeError, e:
            print e;
            client.close();
            pass;

    def process(self):
        try:
            sock, addr = self._serverSocket.accept();
            sock.setblocking(0);
            self._unknownClients[sock] = "";
        except socket.error, e:
            pass;
        
        for client in self._unknownClients.keys():
            self.processClient(client);

    def processClient(self, client):
        try:
            line, self._unknownClients[client] = \
                usarmsg.readLine(client, self._unknownClients[client]);
            while line:
                init = usarmsg.initPattern.match(line);
                if init:
                    self.attachClient((init, usarmsg.initPattern), client);
                    del self._unknownClients[client];
                    return;
                line, self._unknownClients[client] = \
                    usarmsg.readLine(client, self._unknownClients[client]);
        except socket.error, e:
            client.close();
            del self._unknownClients[client];
            if e[0] != errno.EPIPE:
                raise;
